package cz.fimuni.pa165.restfrontend;

import com.google.gson.Gson;
import cz.fimuni.pa165.backendapi.dto.CarDTO;
import cz.fimuni.pa165.backendapi.dto.CompanyDTO;
import cz.fimuni.pa165.restfrontend.propertyeditor.CompanyDTOPropertyEditor;
import cz.fimuni.pa165.restfrontend.validator.CarValidator;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.ModelAndView;

/**
 *
 * @author Ondřej Myška
 */
@Controller
@RequestMapping("/car")
@SessionAttributes("CarDTO")
public class CarController {

    @Autowired
    private CarValidator validator;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private Gson gson;

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(CompanyDTO.class, new CompanyDTOPropertyEditor(gson));
    }

    @RequestMapping(value = "/add", method = RequestMethod.GET)
    public ModelAndView carDTO(Model model) {
        CarDTO car = new CarDTO();
        car.setNumberOfSeats(4);
        car.setColour("černá");
        car.setAvailable(true);
        ModelAndView view = new ModelAndView("/car/add", "carDTO", car);
        try {
            String company = new RestTemplate().getForObject("http://localhost:8080/pa165/rest/company/all", String.class);
            List<CompanyDTO> companyDTO = gson.fromJson(company, List.class);
            
            
            if (companyDTO.isEmpty()){
                return new ModelAndView("redirect:/car");
            } else {
                view.addObject("companies", companyDTO);
            }
            
            
        } catch (HttpClientErrorException e) {
            if (e.getStatusCode() == HttpStatus.NOT_FOUND) {
                return new ModelAndView("remoteServerError");
            }
        }catch (ResourceAccessException e) {
                return new ModelAndView("remoteServerError");
        }
        return view;

    }

    @RequestMapping(value = "/save", method = {RequestMethod.POST, RequestMethod.GET})
    public ModelAndView addCar(@ModelAttribute("carDTO") CarDTO car, BindingResult result) {
        try {
            String json = gson.toJson(car);
            HttpHeaders headers = new HttpHeaders();
            headers.add("Content-Type", "application/json; charset=utf-8");

            HttpEntity request = new HttpEntity(json, headers);
            restTemplate.postForLocation("http://localhost:8080/pa165/rest/car/add", request);
        } catch (HttpClientErrorException e) {

            if (e.getStatusCode() == HttpStatus.BAD_REQUEST) {
                return new ModelAndView("redirect:/car/add");
            }
            if (e.getStatusCode() == HttpStatus.NOT_FOUND) {
                return new ModelAndView("remoteServerError");
            }
        }catch (ResourceAccessException e) {
                return new ModelAndView("remoteServerError");
        }
        return new ModelAndView("redirect:/car");

    }

    @RequestMapping(method = RequestMethod.GET)
    public String listAllCars(Model model) {
        try {
            String result = restTemplate.getForObject("http://localhost:8080/pa165/rest/car/getall", String.class);
            List<CarDTO> yourClassList = gson.fromJson(result, List.class);
            model.addAttribute("list", yourClassList);
        } catch (HttpClientErrorException e) {
            if (e.getStatusCode() == HttpStatus.NOT_FOUND) {
                return "remoteServerError";
            }
        }catch (ResourceAccessException e) {
                return "remoteServerError";
        }
        return "car/list";
    }

    @RequestMapping(value = "/delete/{id}", method = RequestMethod.GET)
    public String deleteCar(@ModelAttribute("carDTO") CarDTO car, ModelMap model) {
        try{
        restTemplate.delete("http://localhost:8080/pa165/rest/car/delete/" + car.getId(), String.class);
        
        }
        catch (HttpClientErrorException e) {
            if (e.getStatusCode() == HttpStatus.NOT_FOUND) {
                return "remoteServerError";
            }
        }catch (ResourceAccessException e) {
                return "remoteServerError";
        }
        return "redirect:/car";
    }

    @RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)
    public ModelAndView editCar(@PathVariable(value = "id") String id, Model model) {
        ModelAndView view=null;
        try{
        String car = new RestTemplate().getForObject("http://localhost:8080/pa165/rest/car/get/" + id, String.class);
        CarDTO carDTO = gson.fromJson(car, CarDTO.class);
         view = new ModelAndView("car/edit", "carDTO", carDTO);
        }
         catch (HttpClientErrorException e) {
            if (e.getStatusCode() == HttpStatus.NOT_FOUND) {
                return new ModelAndView("remoteServerError");
            }
        }catch (ResourceAccessException e) {
                return new ModelAndView("remoteServerError");
        }
        try{
        String company = new RestTemplate().getForObject("http://localhost:8080/pa165/rest/company/all", String.class);
        List<CompanyDTO> companyDTO = gson.fromJson(company, List.class);
        view.addObject("companies", companyDTO);
        }
        catch (HttpClientErrorException e) {
            if (e.getStatusCode() == HttpStatus.NOT_FOUND) {
                return new ModelAndView("remoteServerError");
            }
        }
        return view;

    }

    @RequestMapping(value = "/done", method = RequestMethod.POST)
    public String updateCar(@ModelAttribute("carDTO") CarDTO car, BindingResult result) {
        String json = gson.toJson(car);
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json; charset=utf-8");

        HttpEntity request = new HttpEntity(json, headers);
        try {
            restTemplate.postForLocation("http://localhost:8080/pa165/rest/car/update", request);
        } catch (HttpClientErrorException e) {
            if (e.getStatusCode() == HttpStatus.INTERNAL_SERVER_ERROR) {
                return "remoteServerError";
            }
            if (e.getStatusCode() == HttpStatus.BAD_REQUEST) {
                return "redirect:/car/add";
            }
        }catch (ResourceAccessException e) {
                return "remoteServerError";
        }
        return "redirect:/car";
    }
}
